#include "schedulewidget.h"
#include "ui_schedulewidget.h"
#include <QTableWidget>
#include <QComboBox>
#include <QHeaderView>
#include <QVBoxLayout>
#include <QLabel>
#include <QPushButton>
#include <QSqlQuery>
#include <QDialogButtonBox>
#include <QMessageBox>
#include <QFormLayout>
#include <QTimeEdit>
#include <QSqlError>
#include <Qdebug>
#include <QTableWidgetItem>

int customWeekNumber(const QDate& date) {
    // 计算年度起始日
    const QDate startOfYear(date.year(), 1, 1);

    // 获取年度起始日的星期值（Qt周日=7，周一=1）
    const int dayOfWeek = startOfYear.dayOfWeek();

    // 计算日期距离年初的天数
    const int days = startOfYear.daysTo(date);

    // 计算周数（兼容ISO 8601标准）
    // 公式：周数 = (天数 + 起始日星期偏移 - 1) / 7 + 1
    const int week = (days + dayOfWeek - 1) / 7 + 1;
    return week > 52 ? 1 : week;  // 处理年末最后几天的跨年情况
}

QPair<QDate, QDate> ScheduleWidget::getWeekRange(int year, int week)
{
    // 步骤1：确定年度基准日（可能属于上一年度的最后一周）
    QDate startDate(year, 1, 1);

    // 步骤2：对齐到ISO周起始（周一为每周第一天）
    int daysToSubtract = startDate.dayOfWeek() - Qt::Monday;
    if (daysToSubtract > 0) {
        startDate = startDate.addDays(-daysToSubtract);  // 回退到最近的周一
    }

    // 步骤3：计算目标周范围
    QDate weekStart = startDate.addDays((week - 1) * 7); // 周起始日
    QDate weekEnd = weekStart.addDays(6);                // 周结束日（+6天）

    return qMakePair(weekStart, weekEnd);
}

ScheduleWidget::ScheduleWidget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::ScheduleWidget)
{
    ui->setupUi(this);
    // 初始化界面及数据
    setupUI();

    // 获取当前周次信息
    const int currentYear = QDate::currentDate().year();
    const int currentWeek = customWeekNumber(QDate::currentDate());

    // 设置初始选择状态
    yearComboBox->setCurrentText(QString::number(currentYear));   // 设置当前年份
    weekComboBox->setCurrentText(QString("第%1周").arg(currentWeek));  // 设置当前周次

    // 加载课表数据
    loadSchedule();
}

ScheduleWidget::~ScheduleWidget()
{
    delete ui;
}

void ScheduleWidget::setupUI() {
    /* 初始化用户界面
     * 功能：创建年份和周数选择框、课程表显示区域、操作按钮
     * 并建立信号槽连接
     */

    // 主垂直布局
    QVBoxLayout* mainLayout = new QVBoxLayout(this);

    // 日期选择水平布局
    QHBoxLayout* dateLayout = new QHBoxLayout();

    // 初始化控件
    yearComboBox = new QComboBox(this);
    weekComboBox = new QComboBox(this);
    dateRangeLabel = new QLabel("当前周次：", this);

    // 填充年份选项（2020-当前年份+5年）
    const int currentYear = QDate::currentDate().year();
    for (int year = 2020; year <= currentYear + 5; ++year) {
        yearComboBox->addItem(QString::number(year), year);
    }

    // 填充周数选项（1-52周）
    for (int week = 1; week <= 52; ++week) {
        weekComboBox->addItem(QString("第%1周").arg(week), week);
    }

    // 周导航按钮
    QPushButton* prevWeekBtn = new QPushButton("◀ 上一周", this);
    QPushButton* nextWeekBtn = new QPushButton("下一周 ▶", this);
    prevWeekBtn->setFixedWidth(100);  // 统一按钮宽度
    nextWeekBtn->setFixedWidth(100);

    // 构建日期选择布局
    dateLayout->addWidget(new QLabel("年份:", this));
    dateLayout->addWidget(yearComboBox);
    dateLayout->addSpacing(10);  // 添加间隔

    dateLayout->addWidget(new QLabel("周数:", this));
    dateLayout->addWidget(weekComboBox);
    dateLayout->addSpacing(10);

    dateLayout->addWidget(dateRangeLabel);
    dateLayout->addStretch();  // 填充空白区域
    // dateLayout->addWidget(prevWeekBtn);
    // dateLayout->addWidget(nextWeekBtn);

    tableWidget= new QTableWidget (this);
    tableWidget->setAlternatingRowColors(true);
    tableWidget->setSelectionMode(QAbstractItemView::SingleSelection);
    setupTable();

    // 初始化操作按钮
    addButton = new QPushButton("添加课程", this);
    deleteButton = new QPushButton("删除课程", this);
    addButton->setFixedWidth(120);    // 统一按钮尺寸
    deleteButton->setFixedWidth(120);

    // 信号槽连接
    connect(yearComboBox, QOverload<int>::of(&QComboBox::currentIndexChanged),
            this, &ScheduleWidget::loadSchedule);
    connect(weekComboBox, QOverload<int>::of(&QComboBox::currentIndexChanged),
            this, &ScheduleWidget::loadSchedule);

    connect(addButton,    &QPushButton::clicked,
            this,         &ScheduleWidget::addCourse);
    connect(deleteButton, &QPushButton::clicked,
            this,         &ScheduleWidget::deleteCourse);

    connect(prevWeekBtn,  &QPushButton::clicked,
            this,         &ScheduleWidget::showPreviousWeek);
    connect(nextWeekBtn,  &QPushButton::clicked,
            this,         &ScheduleWidget::showNextWeek);

    connect(tableWidget,  &QTableWidget::itemChanged,
            this,         &ScheduleWidget::handleItemChanged);

    // 创建按钮布局
    QHBoxLayout* buttonLayout = new QHBoxLayout();
    buttonLayout->addStretch();                      // 左侧弹性空间
    buttonLayout->addWidget(prevWeekBtn);           // 上一周按钮
    buttonLayout->addWidget(nextWeekBtn);           // 下一周按钮
    buttonLayout->addSpacing(20);                   // 按钮间距
    buttonLayout->addWidget(addButton);             // 添加课程按钮
    buttonLayout->addWidget(deleteButton);          // 删除课程按钮
    buttonLayout->addStretch();                     // 右侧弹性空间

    // 组装主界面布局
    mainLayout->addLayout(dateLayout);              // 顶部：日期选择
    mainLayout->addWidget(tableWidget);             // 中部：课程表主体
    mainLayout->addLayout(buttonLayout);            // 底部：操作按钮组

    this->setLayout(mainLayout);                    // 应用主布局
}

void ScheduleWidget::setupTable() {
    // 初始化时间标签
    QStringList days = {
        "星期一", "星期二", "星期三",
        "星期四", "星期五", "星期六", "星期日"
    };
    times = {
        "上午1", "上午2",
        "下午1", "下午2",
        "晚上1", "晚上2"
    };

    // 设置表格维度
    tableWidget->setRowCount(times.count());
    tableWidget->setColumnCount(days.count());

    // 获取当前选择的周次信息
    const int year = yearComboBox->currentData().toInt();
    const int week = weekComboBox->currentData().toInt();
    const QPair<QDate, QDate> weekRange = getWeekRange(year, week);
    const QDate startDate = weekRange.first;

    // 生成水平表头（时间段）
    tableWidget->setVerticalHeaderLabels(times);

    // 设置垂直表头（日期段）
    QStringList horizontalHeaders;
    for (int i = 0; i < days.count(); ++i) {
        const QDate currentDate = startDate.addDays(i);
        horizontalHeaders.append(QString("%1\n%2")
                                   .arg(days[i])                      // 星期标签
                                   .arg(currentDate.toString("M/dd")) // 日期格式
                               );
    }
    tableWidget->setHorizontalHeaderLabels(horizontalHeaders);;

    // 配置表格显示属性
    tableWidget->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
    tableWidget->verticalHeader()->setSectionResizeMode(QHeaderView::Stretch);

    // 设置编辑触发方式
    tableWidget->setEditTriggers(QAbstractItemView::DoubleClicked |
                                 QAbstractItemView::EditKeyPressed);
}

void ScheduleWidget::loadSchedule()
{
    setupTable();
    tableWidget->blockSignals(true);  // 防止加载数据时触发itemChanged信号
    tableWidget->clearContents();

    int year = yearComboBox->currentData().toInt();
    int week = weekComboBox->currentData().toInt();

    QPair<QDate, QDate> weekRange = getWeekRange(year, week);
    QDate startDate = weekRange.first;
    QDate endDate = weekRange.second;

    dateRangeLabel->setText(startDate.toString("yyyy-M-dd") + "到" + endDate.toString("yyyy-M-dd"));

    QVector<QVector<QString>> courses(7, QVector<QString>(times.count(), ""));

    QSqlQuery query;
    query.prepare("SELECT date, time, course_name FROM schedule WHERE date BETWEEN ? AND ?");
    query.addBindValue(startDate.toString("yyyy-MM-dd"));
    query.addBindValue(endDate.toString("yyyy-MM-dd"));

    if (query.exec()) {  // 执行查询
        while (query.next()) {  // 遍历查询结果
            QDate date = QDate::fromString(query.value(0).toString(), "yyyy-MM-dd");
            QString time = query.value(1).toString();
            int dayIndex = startDate.daysTo(date);  // 计算日期索引
            int timeIndex = times.indexOf(time);  // 计算时间索引

            if (dayIndex >= 0 && dayIndex < 7 && timeIndex != -1) {
                courses[dayIndex][timeIndex] = query.value(2).toString();  // 更新课程表
            }
        }

        // 填充表格
        for (int day = 0; day < 7; ++day) {
            for (int time = 0; time < times.count(); ++time) {
                QTableWidgetItem* item = new QTableWidgetItem(courses[day][time]);
                item->setTextAlignment(Qt::AlignCenter);
                tableWidget->setItem(day, time, item);
            }
        }
        tableWidget->blockSignals(false);  // 恢复信号
    }
}

void ScheduleWidget::addCourse()
{
    // 获取用户在课程表中选择的行和列索引
    int timeIndex  = tableWidget->currentRow();
    int dayIndex   = tableWidget->currentColumn();
    qDebug()<<timeIndex<<"  "<<dayIndex;
    // 验证用户是否有效选择
    // 注意：Qt返回-1表示未选择任何单元格
    // 单元格存在性检查
    QTableWidgetItem *targetItem = tableWidget->item(timeIndex, dayIndex);
    if (!targetItem) {
        // 可在此处自动创建单元格（按需）
        // targetItem = new QTableWidgetItem();
        // tableWidget->setItem(timeIndex, dayIndex, targetItem);
        QMessageBox::warning(this, "错误", "单元格未初始化");
        return;
    }

    // 占用状态检查
    if (!targetItem->text().isEmpty()) {
        QMessageBox::warning(this, "错误", "该时间段已被占用!");
        return;
    }

    // 检查目标单元格是否已被占用
    // 注意：通过判断单元格文本内容是否为空
    if (!tableWidget->item(timeIndex, dayIndex)->text().isEmpty()) {
        QMessageBox::warning(this, "错误", "该时间段已被占用!");
        return;
    }

    // 创建添加课程的对话框
    QDialog dialog(this);
    dialog.setWindowTitle("添加课程"); // 设置对话框标题

    // 使用表单布局管理器
    QFormLayout layout(&dialog);

    // 初始化学生姓名下拉框
    QComboBox nameCombo;
    // 从数据库加载学生数据
    QSqlQuery nameQuery("SELECT name FROM studentInfo");
    while (nameQuery.next()) {
        // 将查询结果的第一列（name字段）添加到下拉框
        nameCombo.addItem(nameQuery.value(0).toString());
    }

    // 时间预设配置（上午9点到晚上21点）
    QMap<int, QTime> timePresets = {
        {0, QTime(9,  0)},  // 第0列对应09:00
        {1, QTime(11, 0)},  // 第1列对应11:00
        {2, QTime(14, 0)},  // 第2列对应14:00
        {3, QTime(16, 0)},  // 第3列对应16:00
        {4, QTime(19, 0)},  // 第4列对应19:00
        {5, QTime(21, 0)}   // 第5列对应21:00
    };

    QTimeEdit *timeEdit = new QTimeEdit(&dialog); // 创建时间选择控件
    timeEdit->setDisplayFormat("HH:mm"); // 设置24小时制时间格式
    timeEdit->setTime(timePresets.value(timeIndex)); // 根据列索引设置默认时间

    // 添加控件到布局
    layout.addRow("学生姓名：", &nameCombo);
    layout.addRow("课程时间：", timeEdit);

    // 创建按钮组
    QDialogButtonBox buttons(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
    buttons.button(QDialogButtonBox::Ok)->setText("确定");
    buttons.button(QDialogButtonBox::Cancel)->setText("取消");
    layout.addRow(&buttons);

    // 连接信号槽
    connect(&buttons, &QDialogButtonBox::accepted, &dialog, &QDialog::accept);
    connect(&buttons, &QDialogButtonBox::rejected, &dialog, &QDialog::reject);

    // 显示对话框并判断结果
    if (dialog.exec() != QDialog::Accepted) return;
    // 生成课程信息字符串 "姓名,HH:mm"
    QString courseName = QString("%1, %2")
                             .arg(nameCombo.currentText())
                             .arg(timeEdit->time().toString("HH:mm"));

    // 获取日期信息
    int year = yearComboBox->currentData().toInt();
    int week = weekComboBox->currentData().toInt();
    QPair<QDate, QDate> weekRange = getWeekRange(year, week);
    QDate currentDate = weekRange.first.addDays(dayIndex);

    // 获取时间段标识（如"上午1"）
    times = {
        "上午1", "上午2",
        "下午1", "下午2",
        "晚上1", "晚上2"
    };
    qDebug()<<times;
    QString timeSlot = times[timeIndex];

    // 添加事务和错误日志
    QSqlDatabase::database().transaction();
    // 数据库操作
    QSqlQuery query;
    query.prepare("INSERT INTO schedule (date,time,course_name) VALUES (?, ?, ?)");

    // 绑定参数
    query.addBindValue(currentDate.toString("yyyy-MM-dd"));
    query.addBindValue(timeSlot);
    query.addBindValue(courseName);

    // 执行并处理结果
    if (!query.exec()) {
        QSqlDatabase::database().rollback();
        qCritical() << "SQL Error:" << query.lastError().text()
                    << "\nQuery:" << query.lastQuery();
        QMessageBox::critical(this, "错误", "添加失败：" + query.lastError().text());
    } else {
        QSqlDatabase::database().commit();
        loadSchedule();
    }
}

void ScheduleWidget::handleItemChanged(QTableWidgetItem *item)
{
    int day         = item->row();
    int timeSlot    = item->column();
    QString newCourse = item->text().trimmed();
    int year        = yearComboBox->currentData().toInt();
    int week        = weekComboBox->currentData().toInt();
    QPair<QDate, QDate> weekRange = getWeekRange(year, week);
    QDate date      = weekRange.first.addDays(day);
    QString time    = times[timeSlot];
    QSqlQuery query;
    if (newCourse.isEmpty()) {
        // 删除课程
        query.prepare("DELETE FROM schedule WHERE date = ? AND time = ?");
        query.addBindValue(date.toString("yyyy-MM-dd"));
        query.addBindValue(time);
    } else {
        // 使用REPLACE语句更新或插入
        query.prepare("INSERT OR REPLACE INTO schedule (date, time, course_name) VALUES (?, ?, ?)");
        query.addBindValue(date.toString("yyyy-MM-dd"));
        query.addBindValue(time);
        query.addBindValue(newCourse);
    }

    if (!query.exec()) {
        QMessageBox::critical(this, "错误", "操作失败: " + query.lastError().text());
        loadSchedule();  // 恢复数据
    }
}

void ScheduleWidget::deleteCourse()
{
    // 确认删除操作
    QMessageBox confirmBox(this);
    confirmBox.setWindowTitle("确认删除");
    confirmBox.setText("确定要删除该记录吗？");

    // 设置按钮为中文
    QPushButton* yesButton = confirmBox.addButton(
        "确定",
        QMessageBox::YesRole
        );
    QPushButton* noButton = confirmBox.addButton(
        "取消",
        QMessageBox::NoRole
        );

    // 设置默认按钮
    confirmBox.setDefaultButton(noButton);
    // 显示对话框并等待用户选择
    confirmBox.exec();
    if(confirmBox.clickedButton()==yesButton){
        int dayIndex = tableWidget->currentColumn();
        int timeIndex = tableWidget->currentRow();

        if (dayIndex == -1 || timeIndex == -1) {
            QMessageBox::warning(
                this,
                "错误",
                "请先选择一个时间段！"
                );
            return;
        }

        QTableWidgetItem* item = tableWidget->item(dayIndex, timeIndex);

        if (!item || item->text().isEmpty()) {
            QMessageBox::warning(
                this,
                "错误",
                "该时间段没有课程！"
                );
            return;
        }

        int year = yearComboBox->currentData().toInt();
        int week = weekComboBox->currentData().toInt();

        QPair<QDate, QDate> weekRange = getWeekRange(year, week);
        QDate currentDate = weekRange.first.addDays(dayIndex);
        QString time = times[timeIndex];

        QSqlQuery query;
        query.prepare(
            "DELETE FROM schedule "
            "WHERE date = ? AND time = ?"
            );
        query.addBindValue(currentDate.toString("yyyy-MM-dd"));
        query.addBindValue(time);
        if(!query.exec()){
            QMessageBox::critical(this,"错误","删除失败:"+query.lastError().text());
        }else{
            loadSchedule();
        }
    }
}

void ScheduleWidget::showPreviousWeek()
{
    int currentWeek = weekComboBox->currentIndex();
    int currentYear = yearComboBox->currentIndex();

    if (currentWeek > 0) {
        // 直接减少周数
        weekComboBox->setCurrentIndex(currentWeek - 1);
    } else {
        // 需要跨年处理
        if (yearComboBox->currentIndex() > 0) {
            // 减少年份
            yearComboBox->setCurrentIndex(currentYear - 1);
            // 跳转到上一年最后一周（第52周）
            weekComboBox->setCurrentIndex(51);
        }
    }
}

void ScheduleWidget::showNextWeek()
{
    int currentWeek = weekComboBox->currentIndex();
    int currentYear = yearComboBox->currentIndex();

    if (currentWeek < 51) {
        // 正常增加周数
        weekComboBox->setCurrentIndex(currentWeek + 1);
    } else {
        // 处理年份边界
        if (yearComboBox->currentIndex() < yearComboBox->count() - 1) {
            // 切换到下一年
            yearComboBox->setCurrentIndex(currentYear + 1);
            // 重置为新年第一周
            weekComboBox->setCurrentIndex(0);
        }
    }
}
